T1-运动会(sports)
要将 2n 个数分为两组,第 i 个数的值为 ai。
有 m 对关系 (xi,yi,bi) 表示当第 xi 个数和第 yi 个数被分到同一组时,会产生额外 bi 的贡献。
求分组之后两组之间总和差的最大值是多少。
1≤t≤5,1≤n≤105,1≤m≤2×105,1≤xi,yi≤2n,1≤ai,bi≤109。
保证对 ∀1≤i<j≤m,有 (xi,yi)=(xj,yj) 且 (xi,yi)=(yj,xj)。
a 全相等,此时只需考虑朋友关系的贡献。
考虑如下贪心过程:设与 i 相关的朋友关系的默契度之和为 si,则选 s 从大到小排序后的前 n 个人分成一组,剩下的分成另一组,答案即为 21(∑i=1nsi−∑i=n+12nsi)。
证明:对于朋友关系 (x,y,b),如果 (x,y) 在同一组,则对答案的贡献为 2b 或 −2b。否则,贡献为 0,即贡献被抵消掉了。\
复杂度 O(m+nlogn)。
考虑每个人的力量,则将每个 si 额外加上 2si 然后跑上述贪心即可。
T2-卡牌(card)
有 n 张卡牌,每张卡牌背面有一个数字 ai,正面空白。
初始全部正面朝上,可以做以下操作任意次:
- 选择一个 i 满足 1≤i≤m。
- 翻转从左到右第 li,⋯,ri 张牌的正反面,代价为 wi。
设最后背面朝上的卡牌写着的数的总和是 S,所有操作的代价总和为 T,则最终得分为 S−T。
求最大可能得分。
1≤t≤5,1≤n,m≤2×105,1≤li,ri≤n,1≤ai,wi≤109。
每个区间不交,对每个区间单独考虑,每个区间的贡献即为 max(0,(∑i=liriaj)−wi)。
显然每个 li=1 和每个 ri=n 的区间都分别只会被操作其中一个。枚举翻转了 li=1,ri=x 这个前缀,考虑每个 rj=n 的区间。如果 lj>x,则此时答案为 (∑k=1xak)+(∑k=ljnak)−wi−wj。
如果 lj≤x,则还需减去相交部分的和。分别维护即可。
考虑做如下转化:初始答案为 ∑i=1nai。若最后无法翻转 i,视作花费 ai 的代价操作 i 这个点。
因此,初始时先将每个 (i,i,ai) 加入操作中,即转化为操作若干次使所有卡片都被翻转的最小代价。\
我们考虑 建这样一张图:点集为 1∼n+1,边为所有的 (li,ri+1,wi) 和 i,i+1,ai,然后求 1 至 n+1 的最短路即可。易证一条 1 至 n+1 的路径对应了一种将所有卡片翻转的操作方案。
复杂度 O((n+m)log(n+m))。
有 n 个同学,第 i 个同学的初始位置为 xi,需要将每个同学的位置向左或向右移动 d 个单位。
需要将同学分为若干排,设一共站成 k 排,第 i 排的同学的编号集合为 Si,则定义凌乱程度为:
i=1∑ka+b×(j∈Simaxyj−j∈Siminyj)
a,b 为给定常数,求所有可能的队形的凌乱程度的最小值。
1≤t≤5,1≤n≤100,1≤d≤30,1≤a,b≤106,1≤xi≤100。
当 d≤9 时。我们先将题意转化为要求每个人不动或向右移动 2d。
为了方便计算,称第 i 位置被覆盖,为当前位置有人,或者存在两个位置为 l,r(l<r) 的人,使得这两个人被分在同一组,且 l≤i≤r。设 vi 表示位置 i 最终是否被覆盖,则答案为 a×∑ivi+min(0,b−a)×∑i(vi∧vi−1)。
我们的限制形如,对于一个位置 x 的人,要求最后位置 x 和 x+2d 中至少有一个被覆盖。
考虑状态压缩。设 fi,S 表示考虑到位置 i,前 2d 个位置的覆盖情况为 S。设移动后最左和最右的人的位置之差为 V,则这样的状态总数是 O(V×22d) 的。由于 V≤160,因此状态数可以接受。
考虑如何转移。设从左到右到了 i−1,枚举位置 i 是否被覆盖。如果存在一个人的初始位置为 i−2d,则需要要求 i 被覆盖或者 i−2d 被覆盖,这是容易判断的。贡献直接按照上述式子计算即可。复杂度 O(t×V×22d)。
考虑 d 较大的情况。修改一下状态,设 fi,S 表示位置 i,2d+1,4d+1,… 的覆盖情况为 S 从 i 转移到 i+1。所需要的判断和贡献计算都是类似的。此外,我们需要额外记录下 1,2d+1,4d+1,… 的状态,以便在计算完后计算 2d,4d,6d,… 和 1,2d+1,4d+1,… 之间产生的贡献。
这个算法的复杂度为 O(V×2V/d),在 d>9 时可以接受。于是我们在 d≤9 时运行上一个算法,在 d>9 时运行该算法,即可通过所有数据。
T4-二零四八(game)
有一棵 n 个结点的树,初始 i 号结点上有一个数 2ai。
一轮游戏的过程如下:
- 每次可以选择一条边,满足这条边两个端点上的数相等。然后,把这条边缩成一个新点,新点上的数为两个端点上的数之和。
- 如果在重复执行以上操作后,能使树上仅剩一个结点,那么你将获得游戏的胜利。
将进行 q 轮游戏。每轮游戏开始前,会交换某条边两个端点上写着的数。
对于每轮游戏,你想知道是否存在一种方案使你能获胜。注意,每轮游戏之间是独立的,但是修改是永久的。
1≤n,q≤2×105,1≤ai≤n,1≤xi,yi≤n。
m≤10 时,按值从小到大操作,发现合法的充要条件是,对于当前操作到的值 v,所有点值为 2v 的点的导出子图有完美匹配。于是从小到大模拟收缩的过程。
带修改,我们需要一个更好的判定合法的方式,即需要快速对每个操作到的 v,判定其导出子图是否有完美匹配。
这里给出一个结论:假设一个有根树的某些点被染为黑色,其余点为白色。记黑点总数为 s,子树内有奇数个黑点的子树个数记为 t。此时有 ⌊2s⌋≤t。
等号是否成立即为黑点导出子图是否有完美匹配的充要条件。
严格证明可以使用归纳法。感性理解:对于一个黑点 x 满足它的子树黑点数为奇数,那么 x 的父亲必须为黑点。所以这样的子树必须有 s/2 个。
于是我们可以把这个问题拆为两个子问题:对于所有 v,求操作到 v 时点值为 2v 的点的个数,以及求此时有多少个子树内部点数为奇数个 2v。
对于第一个子问题,由于修改并未改变数值性质,所以可以在询问前预处理。
对于第二个子问题,我们考虑计算出每个子树的点值之和 S,那么这个子树在操作到 2v=lowbit(S) 时做贡献。可以用 set 启发式合并维护二进制位,进位数量 O(n) 的,可以直接维护。
对于修改,我们发现只会影响这条边深度较大的那个点的子树内,修改形如减去一个 2i 再加一个 2j。我们把操作拆到在这个点上,在 set 里维护 +1 的连续段,即可做到 O(logn) 加减一个二进制位。
总复杂度 O(nlog2n+mlogn)。